package com.zyl.javabasic.动态代理.demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * InvocationHandler：代理实例的调用处理程序接口。
 * Method：表示类中的方法，通过它可以反射调用目标方法。
 * Proxy：提供静态方法用于创建动态代理类和实例
 *
 *
 */
public class UserServiceProxy implements InvocationHandler {
    private Object target;


    /**
     *
     * Proxy.newProxyInstance() 创建一个代理对象：
     * 参数一：类加载器，用于加载代理类。
     * 参数二：目标对象所实现的所有接口，代理类将实现这些接口。 （*******重点）
     * 参数三：调用处理器，即当前对象 this，它负责处理所有代理对象的方法调用。
     * 返回值是一个代理对象，外部调用该对象的方法时，会自动转发到 invoke() 方法中。
     *
     * @param target
     * @return
     */
    public Object getProxy(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
    }

    /**
     * UserServiceProxy 实现了 InvocationHandler 接口，因此必须重写 invoke() 方法。
     * 这个类是一个通用的代理处理器，可以为任何实现了接口的对象创建代理
     * invoke() 是核心方法，当通过代理对象调用方法时，会执行此方法。
     * 执行流程如下：
     * 前置处理：在目标方法执行前做一些操作（如日志记录、权限校验等）。
     * 调用目标方法：使用 method.invoke(target, args) 调用实际对象的方法。
     * 后置处理：在目标方法执行后做一些操作（如结果处理、日志记录等）。
     * 返回值是目标方法的返回值。
     *
     *
     * @param proxy the proxy instance that the method was invoked on
     *
     * @param method the {@code Method} instance corresponding to
     * the interface method invoked on the proxy instance.  The declaring
     * class of the {@code Method} object will be the interface that
     * the method was declared in, which may be a superinterface of the
     * proxy interface that the proxy class inherits the method through.
     *
     * @param args an array of objects containing the values of the
     * arguments passed in the method invocation on the proxy instance,
     * or {@code null} if interface method takes no arguments.
     * Arguments of primitive types are wrapped in instances of the
     * appropriate primitive wrapper class, such as
     * {@code java.lang.Integer} or {@code java.lang.Boolean}.
     *
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置处理");
        Object result = method.invoke(target, args);
        System.out.println("后置处理");
        return result;
    }
}
